package project11;

/**
 * 算式类的单元测试
 */
class ArithmeticProblem3 {
    int operand1;
    int operand2;
    char operator;
    int result;

    // 构造函数
    public ArithmeticProblem3(int operand1, int operand2, char operator) {
        this.operand1 = operand1;
        this.operand2 = operand2;
        this.operator = operator;
        // 计算结果
        if (operator == '+') {
            this.result = operand1 + operand2;
        } else {
            this.result = operand1 - operand2;
        }
    }

    // 重写toString方法，方便输出（包括答案）
    @Override
    public String toString() {
        return String.format("%2d %c %2d = %3d", operand1, operator, operand2, result);
    }

    // 不带答案的字符串表示
    public String toProblemString() {
        return String.format("%2d %c %2d =   ", operand1, operator, operand2);
    }

    // 重写equals和hashCode方法以支持去重
    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        ArithmeticProblem3 that = (ArithmeticProblem3) obj;
        return operand1 == that.operand1 &&
                operand2 == that.operand2 &&
                operator == that.operator;
    }

    @Override
    public int hashCode() {
        return operand1 * 1000 + operand2 * 10 + operator;
    }

    // 获取唯一标识符用于比较
    public String getKey() {
        return operand1 + "" + operator + "" + operand2;
    }

    // Getter方法用于测试
    public int getOperand1() {
        return operand1;
    }

    public int getOperand2() {
        return operand2;
    }

    public char getOperator() {
        return operator;
    }

    public int getResult() {
        return result;
    }
}

/**
 * 算式类的单元测试类
 */
public class ArithmeticProblemTest {

    public static void main(String[] args) {
        System.out.println("开始对ArithmeticProblem3类进行单元测试...\n");

        // 测试计数器
        int passedTests = 0;
        int totalTests = 0;

        // 测试1: 加法算式构造
        totalTests++;
        if (testAddition()) {
            passedTests++;
            System.out.println("✓ 测试1通过: 加法算式构造正确");
        } else {
            System.out.println("✗ 测试1失败: 加法算式构造错误");
        }

        // 测试2: 减法算式构造
        totalTests++;
        if (testSubtraction()) {
            passedTests++;
            System.out.println("✓ 测试2通过: 减法算式构造正确");
        } else {
            System.out.println("✗ 测试2失败: 减法算式构造错误");
        }

        // 测试3: toString方法
        totalTests++;
        if (testToString()) {
            passedTests++;
            System.out.println("✓ 测试3通过: toString方法正确");
        } else {
            System.out.println("✗ 测试3失败: toString方法错误");
        }

        // 测试4: toProblemString方法
        totalTests++;
        if (testToProblemString()) {
            passedTests++;
            System.out.println("✓ 测试4通过: toProblemString方法正确");
        } else {
            System.out.println("✗ 测试4失败: toProblemString方法错误");
        }

        // 测试5: equals和hashCode方法
        totalTests++;
        if (testEqualsAndHashCode()) {
            passedTests++;
            System.out.println("✓ 测试5通过: equals和hashCode方法正确");
        } else {
            System.out.println("✗ 测试5失败: equals和hashCode方法错误");
        }

        // 测试6: getKey方法
        totalTests++;
        if (testGetKey()) {
            passedTests++;
            System.out.println("✓ 测试6通过: getKey方法正确");
        } else {
            System.out.println("✗ 测试6失败: getKey方法错误");
        }

        // 测试7: 加法结果范围检查
        totalTests++;
        if (testAdditionResultRange()) {
            passedTests++;
            System.out.println("✓ 测试7通过: 加法结果范围正确");
        } else {
            System.out.println("✗ 测试7失败: 加法结果超出范围");
        }

        // 测试8: 减法结果范围检查
        totalTests++;
        if (testSubtractionResultRange()) {
            passedTests++;
            System.out.println("✓ 测试8通过: 减法结果范围正确");
        } else {
            System.out.println("✗ 测试8失败: 减法结果超出范围");
        }

        // 输出测试结果总结
        System.out.println("\n==================== 测试结果 ====================");
        System.out.println("总测试数: " + totalTests);
        System.out.println("通过测试: " + passedTests);
        System.out.println("失败测试: " + (totalTests - passedTests));
        System.out.println("通过率: " + String.format("%.2f", (passedTests * 100.0 / totalTests)) + "%");

        if (passedTests == totalTests) {
            System.out.println("🎉 所有测试通过!");
        } else {
            System.out.println("❌ 部分测试未通过，请检查代码。");
        }
    }

    // 测试加法算式构造
    private static boolean testAddition() {
        try {
            ArithmeticProblem3 problem = new ArithmeticProblem3(10, 20, '+');
            return problem.getOperand1() == 10 &&
                    problem.getOperand2() == 20 &&
                    problem.getOperator() == '+' &&
                    problem.getResult() == 30;
        } catch (Exception e) {
            return false;
        }
    }

    // 测试减法算式构造
    private static boolean testSubtraction() {
        try {
            ArithmeticProblem3 problem = new ArithmeticProblem3(30, 15, '-');
            return problem.getOperand1() == 30 &&
                    problem.getOperand2() == 15 &&
                    problem.getOperator() == '-' &&
                    problem.getResult() == 15;
        } catch (Exception e) {
            return false;
        }
    }

    // 测试toString方法
    private static boolean testToString() {
        try {
            ArithmeticProblem3 problem = new ArithmeticProblem3(5, 8, '+');
            String result = problem.toString();
            return result.equals(" 5 +  8 =  13") || result.matches("\\s*5\\s*\\+\\s*8\\s*=\\s*13");
        } catch (Exception e) {
            return false;
        }
    }

    // 测试toProblemString方法
    private static boolean testToProblemString() {
        try {
            ArithmeticProblem3 problem = new ArithmeticProblem3(12, 7, '-');
            String result = problem.toProblemString();
            return result.equals("12 -  7 =   ") || result.matches("\\s*12\\s*\\-\\s*7\\s*=\\s*");
        } catch (Exception e) {
            return false;
        }
    }

    // 测试equals和hashCode方法
    private static boolean testEqualsAndHashCode() {
        try {
            ArithmeticProblem3 problem1 = new ArithmeticProblem3(10, 5, '+');
            ArithmeticProblem3 problem2 = new ArithmeticProblem3(10, 5, '+');
            ArithmeticProblem3 problem3 = new ArithmeticProblem3(10, 5, '-');

            // 相同的算式应该相等
            boolean equalCheck = problem1.equals(problem2);

            // 相同的算式应该有相同的hashCode
            boolean hashCodeCheck = problem1.hashCode() == problem2.hashCode();

            // 不同的算式不应该相等
            boolean notEqualCheck = !problem1.equals(problem3);

            return equalCheck && hashCodeCheck && notEqualCheck;
        } catch (Exception e) {
            return false;
        }
    }

    // 测试getKey方法
    private static boolean testGetKey() {
        try {
            ArithmeticProblem3 problem = new ArithmeticProblem3(25, 10, '-');
            String key = problem.getKey();
            return key.equals("25-10");
        } catch (Exception e) {
            return false;
        }
    }

    // 测试加法结果范围
    private static boolean testAdditionResultRange() {
        try {
            // 测试正常范围内的加法
            ArithmeticProblem3 problem1 = new ArithmeticProblem3(30, 40, '+');
            if (problem1.getResult() != 70) return false;

            // 测试边界值加法
            ArithmeticProblem3 problem2 = new ArithmeticProblem3(100, 0, '+');
            if (problem2.getResult() != 100) return false;

            ArithmeticProblem3 problem3 = new ArithmeticProblem3(50, 50, '+');
            if (problem3.getResult() != 100) return false;

            return true;
        } catch (Exception e) {
            return false;
        }
    }

    // 测试减法结果范围
    private static boolean testSubtractionResultRange() {
        try {
            // 测试正常范围内的减法
            ArithmeticProblem3 problem1 = new ArithmeticProblem3(50, 30, '-');
            if (problem1.getResult() != 20) return false;

            // 测试边界值减法
            ArithmeticProblem3 problem2 = new ArithmeticProblem3(100, 100, '-');
            if (problem2.getResult() != 0) return false;

            ArithmeticProblem3 problem3 = new ArithmeticProblem3(50, 0, '-');
            if (problem3.getResult() != 50) return false;

            return true;
        } catch (Exception e) {
            return false;
        }
    }
}
